#pragma  once

#include "core/log.h"
#include "core/stringhelper.h"
//#include "Core/String/stringhelper.h"

enum proptype
{
	prop_int,
	prop_float,
	prop_angle,
	prop_float2,
	prop_float3,
	prop_float4,
	prop_float4x4,
	prop_string,
	prop_stringhash,
	prop_stringhashlist,
	prop_bool,
	prop_color4f,
//	prop_mesh,
//	prop_collimesh,
	//	prop_TREF_TEXTURE,
	prop_sound,
//	prop_tick,
	prop_enum,
//	prop_natural_spline_t,
//	prop_sphere,
	prop_array,
//	prop_entity_id,
	prop_stringlist,
	prop_json_property,

	prop_num
};





//////////////////////////////////////////////////////////////////////////
//		property descriptor
//////////////////////////////////////////////////////////////////////////
struct property_t
{
	property_t(stringhash i_name,proptype i_type,unsigned i_offset):name(i_name),m_offset(i_offset),m_type(i_type), data(0)
	{
#ifdef LEO_DESIGNER
		m_description="";
		m_editoronly=false;
#endif
	}

	virtual ~property_t(){}

#ifdef LEO_DESIGNER
/*
	const stringhash& get_name() const
	{
		return m_name;
	}
*/

	string to_string(void* i_obj)
	{
		string s;
		s+="\"";
		s+=name.c_str();
		s+="\" : ";
		add_value_to_string(i_obj,s);
		return s;
	}
#endif

	proptype get_type() const
	{
		return m_type;
	}

	unsigned get_offset() const
	{
		return m_offset;
	}

	char* get_address(void* e)
	{
		return (char*)(e)+m_offset;
	}

	void load_value(void* i_object, json_object_t* obj)
	{
		json_value_t* val=obj->get_value(name);

		if (val)
			load_value(i_object,val);
	}
	virtual void load_value(void* i_object, json_value_t* val)=0;
	virtual void clone(void* edst, void* esrc) =0;
#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)=0;
#endif

	void copy_bytes(void* edst, void* esrc, int byte_count)
	{
		memcpy(get_address(edst),get_address(esrc),byte_count);
	}

	template<typename T>
	void copy(void* edst, void* esrc)
	{
		*(T*)get_address(edst)=*(T*)get_address(esrc);
	}

	template<typename T>
	void set(void* e, const T& val)
	{
		(T&)(*((char*)(e)+m_offset))=val;
	}

	template<typename T>
	T& get(void* e)
	{
		return (T&)(*((char*)(e)+m_offset));
	}

	template<typename T>
	const T& get(void* e) const
	{
		return (T&)(*((char*)(e)+m_offset));
	}

	stringhash name;
	proptype m_type;
	unsigned m_offset;

#ifdef LEO_DESIGNER
	const char* m_description;
	bool m_editoronly;
#endif

	void* data;

};//struct




//////////////////////////////////////////////////////////////////////////
// json property
//////////////////////////////////////////////////////////////////////////

struct json_property_t:property_t
{
	json_property_t(stringhash name, unsigned offset):property_t(name,prop_json_property,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_object());
		json_object_t& o=get<json_object_t>(i_object);
		o.copy(val->get_object());
	}

	virtual void clone(void* edst, void* esrc)
	{
		json_object_t& d=get<json_object_t>(edst);
		json_object_t& s=get<json_object_t>(esrc);
		d.copy(s);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		s+=save_json_to_string(&get<json_object_t>(e));
	}
#endif
};








//////////////////////////////////////////////////////////////////////////
// int property
//////////////////////////////////////////////////////////////////////////

struct int_property_t:property_t
{
	int_property_t(stringhash name, unsigned offset):property_t(name,prop_int,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_num()|| val->is_int());
		if (val->is_num())
			set<int>(i_object,(int)val->get_num());
		else
			set<int>(i_object,val->get_int());
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<int>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		sprintf(str,"%d",get<int>(e));
		s+=string(str);
	}
#endif

	int get_int(void* i_object) const
	{
		return get<int>(i_object);
	}
};



//////////////////////////////////////////////////////////////////////////
// bool property
//////////////////////////////////////////////////////////////////////////

struct bool_property_t:property_t
{
	bool_property_t(stringhash name, unsigned offset):property_t(name,prop_bool,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_bool());
		set<bool>(i_object,val->get_bool());
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<bool>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		if (get<bool>(e))
			s+=string("true");
		else
			s+=string("false");
	}
#endif

	bool get_bool(void* i_object) const
	{
		return get<bool>(i_object);
	}
};


//////////////////////////////////////////////////////////////////////////
// float property
//////////////////////////////////////////////////////////////////////////

struct float_property_t:property_t
{
	float_property_t(stringhash name, unsigned offset):property_t(name,prop_float,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_num() || val->is_int());
		set<float>(i_object,(float)val->get_num());
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		sprintf(str,"%.4f",get_float(e));
		s+=string(str);
	}
#endif

	float get_float(void* i_object) const
	{
		return get<float>(i_object);
	}
};


//////////////////////////////////////////////////////////////////////////
// angle property
//////////////////////////////////////////////////////////////////////////

struct angle_property_t:property_t
{
	angle_property_t(stringhash name, unsigned offset):property_t(name,prop_angle,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_num() || val->is_int());
		set<float>(i_object,(float)val->get_num()/RAD2DEG);
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		sprintf(str,"%.4f",get_angle(e));
		s+=string(str);
	}
#endif

	float get_angle(void* i_object) const
	{
		return get<float>(i_object)*RAD2DEG;
	}
};


//////////////////////////////////////////////////////////////////////////
// string property
//////////////////////////////////////////////////////////////////////////

struct string_property_t:property_t
{
	string_property_t(stringhash name, unsigned offset):property_t(name,prop_string,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_str());

		if (data)
		{
			set<string>(i_object,stringhelper::remove_extension(stringhelper::fixup(val->get_str())));
		}
		else
		{
			set<string>(i_object,val->get_str());
		}
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<string>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		s+=string("\"")+get<string>(e)+string("\"");
	}
#endif
	// 	string get_angle(void* i_object) const
	// 	{
	// 		return get<string>(i_object);
	// 	}
};

//////////////////////////////////////////////////////////////////////////
// stringhash property
//////////////////////////////////////////////////////////////////////////

struct stringhash_property_t:property_t
{
	stringhash_property_t(stringhash name, unsigned offset):property_t(name,prop_stringhash,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_str() || val->is_hash());

		if (data)
		{
			//			set<string>(i_object,stringhelper::remove_extension(stringhelper::fixup(val->get_str())));
			if (val->is_str())
				set<stringhash>(i_object,stringhash::get(stringhelper::remove_extension(stringhelper::fixup(val->get_str()))));
			else
				set<stringhash>(i_object,val->get_hash());
		}
		else
		{
			if (val->is_str())
				set<stringhash>(i_object,stringhash::get(val->get_str()));
			else
				set<stringhash>(i_object,val->get_hash());
		}
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<stringhash>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		s+=string("\'")+string(get<stringhash>(e).c_str())+string("\'");
	}
#endif
};

//////////////////////////////////////////////////////////////////////////
//		enum property
//////////////////////////////////////////////////////////////////////////

struct enum_property_t:property_t
{
	enum_property_t(stringhash name, unsigned offset):property_t(name,prop_enum,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		set<int>(i_object,(int)val->get_num());
	}
	virtual void clone(void* edst, void* esrc)
	{
		copy<int>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		sprintf(str,"%d",get<int>(e));
		s+=string(str);
	}
#endif
};


//////////////////////////////////////////////////////////////////////////
//		float2 property
//////////////////////////////////////////////////////////////////////////

struct float2_property_t:property_t
{
	float2_property_t(stringhash name, unsigned offset):property_t(name,prop_float2,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_array() && val->get_array().value_list.size()==2);
		const vector<json_value_t>& vec=val->get_array().value_list;
		set<float2>(i_object,float2((float)vec[0].get_num(),(float)vec[1].get_num()));
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float2>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		float2 v=get<float2>(e);
		sprintf(str,"[ %.4f, %.4f ]",v.x,v.y);
		s+=string(str);
	}
#endif
};

#if 0
//////////////////////////////////////////////////////////////////////////
//		int2 property
//////////////////////////////////////////////////////////////////////////

struct int2_property_t:property_t
{
	int2_property_t(stringhash name, unsigned offset):property_t(name,prop_int2,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_array() && val->get_array().value_list.size()==2);
		const vector<json_value_t>& vec=val->get_array().value_list;
		set<int2>(i_object,int2((int)vec[0].get_num(),(int)vec[1].get_num()));
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float2>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		int2 v=get<int2>(e);
		sprintf(str,"[ %d, %d ]",v.x,v.y);
		s+=string(str);
	}
#endif
};
#endif


//////////////////////////////////////////////////////////////////////////
//		float3 property
//////////////////////////////////////////////////////////////////////////

struct float3_property_t:public property_t
{
	float3_property_t(stringhash name, unsigned offset):property_t(name,prop_float3,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_array() && val->get_array().value_list.size()==3);
		const vector<json_value_t>& vec=val->get_array().value_list;
		set<float3>(i_object,float3((float)vec[0].get_num(),(float)vec[1].get_num(),(float)vec[2].get_num()));
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float3>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		float3 v=get<float3>(e);
		sprintf(str,"[ %.4f, %.4f, %.4f ]",v.x,v.y,v.z);
		s+=string(str);
	}
#endif
};

//////////////////////////////////////////////////////////////////////////
//		float4 property
//////////////////////////////////////////////////////////////////////////

struct float4_property_t:public property_t
{
	float4_property_t(stringhash name, unsigned offset):property_t(name,prop_float4,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_array() && val->get_array().value_list.size()==4);
		const vector<json_value_t>& vec=val->get_array().value_list;
		set<float4>(i_object,float4((float)vec[0].get_num(),(float)vec[1].get_num(),(float)vec[2].get_num(),(float)vec[3].get_num()));
	}

	virtual void clone(void* edst, void* esrc)
	{
		copy<float4>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		float4 v=get<float4>(e);
		sprintf(str,"[ %.4f, %.4f, %.4f, %.4f ]",v.x,v.y,v.z,v.w);
		s+=string(str);
	}
#endif
};

//////////////////////////////////////////////////////////////////////////
//	float4x4 property
//////////////////////////////////////////////////////////////////////////

struct float4x4_property_t:property_t
{
	float4x4_property_t(stringhash n,unsigned offs):property_t(n,prop_float4x4,offs){}

	virtual void load_value(void* i_object,json_value_t* val)
	{
		ASSERT(val->is_object() && val->get_object().pair_list.size()==3);
		float3 m[3];
		vector<json_pair_t>& p=val->get_object().pair_list;

		for (unsigned n=0; n<3; ++n)
		{
			json_value_t* val=&p[n].val;
			ASSERT(val->is_array() && val->get_array().value_list.size()==3);
			const json_array_t& arr=val->get_array();
			const vector<json_value_t>& vec=arr.value_list;
			m[n]=float3((float)vec[0].get_num(),(float)vec[1].get_num(),(float)vec[2].get_num());
		}

		float4x4 mtx;
		mtx._14=mtx._24=mtx._34=0; mtx._44=1;
		mtx.from_rotation(m[1].y*DEG2RAD,m[1].x*DEG2RAD,m[1].z*DEG2RAD);
		mtx.scale(m[2].x,m[2].y,m[2].z);
		mtx.axis(3)=m[0];
		set<float4x4>(i_object,mtx);

	}
	virtual void clone(void* edst, void* esrc)
	{
		copy<float4x4>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		float4x4 mtx=get<float4x4>(e);
		float rx,ry,rz;
		float sx,sy,sz;
		float tx,ty,tz;
		sx=length(mtx.axis(0));
		sy=length(mtx.axis(1));
		sz=length(mtx.axis(2));


		mtx.axis(0)/=sx;
		mtx.axis(1)/=sy;
		mtx.axis(2)/=sz;

		float Yaw,Pitch,Roll;
		mtx.to_rotation(Yaw,Pitch,Roll);
		rx=Pitch*RAD2DEG;
		if (rx<-179.999f)
			rx=180;
		else if (fabsf(rx)<0.0001f)
			rx=0;
		ry=Yaw*RAD2DEG;
		if (ry<-179.999f)
			ry=180;
		else if (fabsf(ry)<0.0001f)
			ry=0;
		rz=Roll*RAD2DEG;
		if (rz<-179.999f)
			rz=180;
		else if (fabsf(rz)<0.0001f)
			rz=0;

		tx=mtx.axis(3).x;
		ty=mtx.axis(3).y;
		tz=mtx.axis(3).z;

		char str[1024];
		sprintf(str,"\n{\n\"Position\" : [%.3f,%.3f,%.3f],\n\"Rotation\" : [%.3f,%.3f,%.3f],\n\"Scale\" : [%.3f,%.3f,%.3f]\n}",tx,ty,tz,rx,ry,rz,sx,sy,sz);
		s+=str;
	}
#endif
};



//////////////////////////////////////////////////////////////////////////
//	color4f property
//////////////////////////////////////////////////////////////////////////

struct color4f_property_t:property_t
{
	color4f_property_t(stringhash n,unsigned offs):property_t(n,prop_color4f,offs){}

	virtual void load_value(void* i_object,json_value_t* val)
	{
		ASSERT(val->is_array() && val->get_array().value_list.size()==4);
		const vector<json_value_t>& vec=val->get_array().value_list;
		set<float4>(i_object,float4((float)vec[0].get_num(),(float)vec[1].get_num(),(float)vec[2].get_num(),(float)vec[3].get_num()));
	}
	virtual void clone(void* edst, void* esrc)
	{
		copy<float4>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		char str[1024];
		float4 c=get<float4>(e);
		sprintf(str,"[ %.4f, %.4f, %.4f, %.4f ]",c.x,c.y,c.z,c.w);
		s+=string(str);
	}
#endif
};


struct sphere_t
{
	float3 center;
	float radius;
#ifdef LEO_DESIGNER
	bool selected;
#endif

	sphere_t()
	{
#ifdef LEO_DESIGNER
		selected=false;
#endif
	}
	sphere_t(const float3& c, float r):center(c),radius(r)
	{
#ifdef LEO_DESIGNER
		selected=false;
#endif
	}
};
//////////////////////////////////////////////////////////////////////////
//		sphere property
//////////////////////////////////////////////////////////////////////////

/*
struct sphere_property_t:property_t
{
	sphere_property_t(stringhash name,unsigned offset):property_t(name,prop_sphere,offset){}

	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_object());
		json_object_t* p=&val->get_object();
		json_value_t* v;

		v=p->get_value("center");

		sphere_t& a=get<sphere_t>(i_object);

		if (v)
		{
			ASSERT(v->is_array());
			const vector<json_value_t>& vec=v->get_array().value_list;
			a.center.set((float)vec[0].get_num(),(float)vec[1].get_num(),(float)vec[2].get_num());

		}

		v=p->get_value("radius");
		if (v)
			a.radius=(float)v->get_num();
	}

	virtual void clone(void* dst, void* src)
	{
		copy<sphere_t>(dst,src);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void*e, string& s)
	{
		sphere_t& a=get<sphere_t>(e);

		char str[1024];
		sprintf(str,"\n{\n\"center\" : [%.3f,%.3f,%.3f],\n\"radius\" : %.4f	\n}",a.center.x,a.center.y,a.center.z,a.radius);
		s+=str;
	}
#endif
};
*/


//////////////////////////////////////////////////////////////////////////
//		array property
//////////////////////////////////////////////////////////////////////////

struct prop_array_base_t
{
	virtual void resize_array(int size)=0;
	virtual void* get_elem_ptr(int index)=0;
	virtual int get_size() const=0;
	virtual void copy(prop_array_base_t& other)=0;
	virtual ~prop_array_base_t(){};
};

template<typename T>
struct prop_array_t:vector<T>,prop_array_base_t
{
	virtual void copy(prop_array_base_t& other)
	{
		*this=(prop_array_t<T>&)other;
	}
	virtual void resize_array(int size)
	{
		vector<T>::resize(size);
	}

	virtual int get_size() const
	{
		return vector<T>::size();
	}

	virtual void* get_elem_ptr(int index)
	{
		return &(this->operator [](index));
	}
};


struct array_property_t:property_t
{
	array_property_t(stringhash name,unsigned offset, property_t* base_prop):property_t(name,prop_array,offset)
	{
		base_property=base_prop;
	}

	~array_property_t()
	{
		delete base_property;
	}

	virtual void load_value(void* i_object,json_value_t* val)
	{
		ASSERT(val->is_array());
		json_array_t* arr=&val->get_array();
		vector<json_value_t>& vec=arr->value_list;

		prop_array_base_t& a=get<prop_array_base_t>(i_object);

		a.resize_array(vec.size());

		for (unsigned int n=0; n<vec.size(); ++n)
		{
			void* ptr=a.get_elem_ptr(n);
			base_property->load_value((void*)(ptr),&vec[n]);
		}

	}
	virtual void clone(void* edst, void* esrc)
	{
		get<prop_array_base_t>(edst).copy(get<prop_array_base_t>(esrc));
		//		copy<prop_array_base_t>(edst,esrc);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void* e,string& s)
	{
		prop_array_base_t& a=get<prop_array_base_t>(e);
		s+="[ ";
		for (int n=0; n<a.get_size()-1; ++n)
		{
			void* ptr=a.get_elem_ptr(n);
			base_property->add_value_to_string((void*)ptr,s);
			s+=", ";
		}

		if (a.get_size())
		{
			void* ptr=a.get_elem_ptr(a.get_size()-1);
			base_property->add_value_to_string((void*)ptr,s);
		}
		s+=string(" ]");
	}
#endif
	property_t* base_property;
};

struct natural_spline_node
{
	float3 pos;
	float3 rot;
	float time;
#ifdef LEO_DESIGNER
	bool selected;
#endif

	natural_spline_node()
	{
		pos.set(0,0,0);
		rot.set(0,0,0);
		time=0;
#ifdef LEO_DESIGNER
		selected=false;
#endif
	}
};

struct hermite_spline_node
{
	float3 pos;
	float3 dpos;
	float3 rot;
	float3 drot;
	float time;
#ifdef LEO_DESIGNER
	bool selected;
#endif

	hermite_spline_node()
	{
		pos.set(0,0,0);
		dpos.set(0,0,0);
		rot.set(0,0,0);
		drot.set(0,0,0);
		time=0;
#ifdef LEO_DESIGNER
		selected=false;
#endif
	}
};


struct tcb_spline_node
{
	float3 pos;
	float3 rot;
	float3 tcb;
	float time;
#ifdef LEO_DESIGNER
	bool selected;
#endif

	tcb_spline_node()
	{
		pos.set(0,0,0);
		rot.set(0,0,0);
		tcb.set(0,0,0);
		time=0;
#ifdef LEO_DESIGNER
		selected=false;
#endif
	}
};

struct stringlist_property_t:property_t
{
	stringlist_property_t(stringhash name, unsigned offset):property_t(name,prop_stringlist,offset){}
	virtual void load_value(void* i_object, json_value_t* val)
	{
		json_array_t& p=val->get_array();
		vector<string>& stringlist=get<vector <string> >(i_object);
		stringlist.clear();
		for (uint32 n=0; n<p.value_list.size(); ++n)
		{
			stringlist.push_back(p.value_list[n].get_str().c_str());
		}
	}
	virtual void clone(void* dst, void* src)
	{
		copy<vector< string> >(dst,src);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void*e, string& s)
	{
		vector<string >& stringlist=get<vector< string> >(e);
		s+="[\n";
		for (unsigned n=0; n<stringlist.size(); ++n)
		{
			s+="\""+stringlist[n]+"\"";
			if (n<stringlist.size()-1)
				s+=",";

			s+="\n";
		}
		s+="]\n";
	}
#endif
};


#if 0
#include "core/Math/natural_spline.h"
struct natural_spline_t_property_t:property_t
{
	natural_spline_t_property_t(stringhash name,unsigned offset):property_t(name,prop_natural_spline_t,offset){}

	virtual void load_value(void* i_object, json_value_t* val)
	{
		ASSERT(val->is_object());
		json_object_t* p=&val->get_object();
		json_value_t* v=p->get_value(__Hash("keys"));
		json_array_t* arr=&v->get_array();

		natural_spline_t& a=get<natural_spline_t>(i_object);
		bool closed=get_bool(p,"closed");
		int keynum=arr->value_list.size();
		float3 pos[1024];
		float3 rot[1024];
		float time[1024];
		for (int n=0; n<keynum; ++n)
		{
			json_value_t& actkeyval=arr->value_list[n];
			json_object_t* o=&actkeyval.get_object();

			pos[n]=get_float3(o,"pos");

			if (o->get_value("rot"))
				rot[n]=get_float3(o,"rot");

			v=o->get_value("yaw");
			if (v)
				rot[n].x=-(float)v->get_num()-90;
			v=o->get_value("pitch");
			if (v)
				rot[n].y=-(float)v->get_num();
			v=o->get_value("roll");
			if (v)
				rot[n].z=-(float)v->get_num();

			time[n]=get_float(o,"time");
		}
		a.set(keynum,pos,rot,time,closed);
	}

	virtual void clone(void* dst, void* src)
	{
		copy<natural_spline_t>(dst,src);
	}

#ifdef LEO_DESIGNER
	virtual void add_value_to_string(void*e, string& s)
	{
		natural_spline_t& a=get<natural_spline_t>(e);

		string tmps;
		tmps+="\n{\n\"closed\" : ";
		tmps+=a.closed ? "true" : "false";
		tmps+=",\n\"keys\" : [";

		for (int n=0; n<a.node_num; ++n)
		{
			char str[1024];
			sprintf(str,"\n{\n\"time\" : %.4f,\n\"pos\" : [%.3f,%.3f,%.3f],\n\"rot\" : [%.3f,%.3f,%.3f]\n}",a.t[n],a.pos[n].x,a.pos[n].y,a.pos[n].z,a.rot[n].x,a.rot[n].y,a.rot[n].z);
			tmps+=str;
			if (n<a.node_num-1)
				tmps+=" , ";
		}
		tmps+="]\n}";
		s+=tmps;
	}
#endif
};

#endif



